import { Injectable, UnauthorizedException,HttpException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { LoginOutputDto } from '../schames/login.dto';
import * as  bcrypt from 'bcryptjs';
import { PrismaService } from '../prisma/prisma.service';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class AuthService {
  constructor(
    private usersService: PrismaService,
    private jwtService: JwtService,
    private configService: ConfigService, // 添加ConfigService依赖
  ) { }

  async login(username: string, password: string): Promise<LoginOutputDto> {
    const user = await this.usersService.user.findFirst({
      where: { username },
    });
    const errMsg = 'username or password error';
    console.log(1);
    if (!user) {
      throw new UnauthorizedException(errMsg);
    }
    // 使用存储的盐值验证密码
    console.log(2);
    const isMatching = bcrypt.compareSync(password, user.password);
    console.log(3);
    if (!isMatching) {
      throw new UnauthorizedException(errMsg);
    }
    const payload = { sub: user.id, username: user.username };
    // 生成新的refresh_token 将refresh_token存储到用户信息refresh_token字段中
    // const refreshToken = await this.jwtService.signAsync(payload, {
    //   secret: this.configService.get('JWT_REFRESH_SECRET'),
    //   expiresIn: this.configService.get('JWT_REFRESH_EXPIRES_IN'),
    // });
    
    //  保存refresh_token到数据库
    // await this.usersService.user.update({
    //   where: { id: user.id },
    //   data: { refreshToken },
    // });
    console.log(4);
    return {
      access_token: await this.jwtService.signAsync(payload)
    };
  }

  async register(username: string, password: string) {
    // 生成盐值
    const salt = bcrypt.genSaltSync(10);
    // 使用生成的盐值哈希密码
    const hashedPassword = bcrypt.hashSync(password, salt);
    // 将盐值和哈希后的密码一起存储
    try {
      const user = await this.usersService.user.create({
        data: {
          username,
          password: hashedPassword,
          salt,
          // 其他必需字段设置默认值
          status: 1,
          gender: 0,
          age: 0
        }
      });
      return user
    } catch (error) {
      throw new HttpException('用户创建失败',500);
    }
  }

  async isUsernameDuplicate(username: string) {
    return { isDuplicate: !!await this.usersService.user.findFirst({ where: { username } }) };
  }

  async getUsers(id: string) {
    const res = await this.usersService.user.findFirst({where: { id }});
    return res;
  }

   // 添加刷新令牌的方法
   async refreshToken(refreshToken: string): Promise<LoginOutputDto> {
    try {
      // 验证refresh_token
      const payload = await this.jwtService.verifyAsync(refreshToken, {
        secret: this.configService.get('JWT_REFRESH_SECRET'),
      });
      
      // 查找用户并验证refresh_token匹配
      const user = await this.usersService.user.findFirst({
        where: { id: payload.sub, refreshToken },
      });
      
      if (!user) {
        throw new UnauthorizedException('Invalid refresh token');
      }
      
      // 生成新的access_token
      const newPayload = { sub: user.id, username: user.username };
      const newAccessToken = await this.jwtService.signAsync(newPayload, {
        secret: this.configService.get('JWT_SECRET'),
        expiresIn: this.configService.get('JWT_EXPIRES_IN'),
      });
      
      // 生成新的refresh_token
      const newRefreshToken = await this.jwtService.signAsync(newPayload, {
        secret: this.configService.get('JWT_REFRESH_SECRET'),
        expiresIn: this.configService.get('JWT_REFRESH_EXPIRES_IN'),
      });
      
      // 更新数据库中的refresh_token
      await this.usersService.user.update({
        where: { id: user.id },
        data: { refreshToken: newRefreshToken },
      });
      
      return {
        access_token: newAccessToken,
        refresh_token: newRefreshToken
      };
      
    } catch (error) {
      throw new UnauthorizedException('Invalid refresh token');
    }
  }
}